{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "设置仿真参数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 95,
   "metadata": {},
   "outputs": [],
   "source": [
    "import random\n",
    "import simpy\n",
    "\n",
    "RANDOM_SEED = 42\n",
    "REQ_TOTAL = 100 # 总请求数\n",
    "ARRIVAL_RATE =   0.05 # 请求到达率 (每毫秒来多少个请求)\n",
    "SERVICE_RATE =   0.1  # 服务速率   (每毫秒做多少个请求)\n",
    "OVER_TIME    = 100.0  # 请求超时   (毫秒)\n",
    "\n",
    "latency = [] # 采集请求延迟\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "初始化仿真对象"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 96,
   "metadata": {},
   "outputs": [],
   "source": [
    "def workload(env, number, arr_rate, server):\n",
    "    \"\"\"基于所设均值泊松分布生成请求\"\"\"\n",
    "    for i in range(number):\n",
    "        c = req_handler(env, 'Request%03d' % i, server, svr_rate=SERVICE_RATE)\n",
    "        env.process(c)\n",
    "        t = random.expovariate(arr_rate)\n",
    "        yield env.timeout(t)\n",
    "\n",
    "def req_handler(env, name, server, svr_rate):\n",
    "    \"\"\"请求处理过程\"\"\"\n",
    "    arrive = env.now\n",
    "    print('%7.4f %s: Incoming request' % (arrive, name))\n",
    "\n",
    "    with server.request() as req:\n",
    "        # ot = random.uniform(MIN_PATIENCE, MAX_PATIENCE)\n",
    "        ot = random.uniform(1, 3)\n",
    "        # 等待服务或超时\n",
    "        results = yield req | env.timeout(OVER_TIME)\n",
    "\n",
    "        wait = env.now - arrive\n",
    "\n",
    "        if req in results:\n",
    "            # We got to the server\n",
    "            print('%7.4f %s: Waited %6.3f' % (env.now, name, wait))\n",
    "\n",
    "            tib = random.expovariate(svr_rate)\n",
    "            yield env.timeout(tib)\n",
    "            print('%7.4f %s: Finished' % (env.now, name))\n",
    "\n",
    "            # 请求正常完成，采集延迟\n",
    "            latency.append(env.now - arrive)\n",
    "\n",
    "        else:\n",
    "            # 请求超时\n",
    "            print('%7.4f %s: Overtime after %6.3f' % (env.now, name, wait))\n",
    "\n",
    "# 仿真环境准备\n",
    "random.seed(RANDOM_SEED)\n",
    "env = simpy.Environment()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "开始仿真"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 97,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      " 0.0000 Request000: Incoming request\n",
      " 0.0000 Request000: Waited  0.000\n",
      " 3.2162 Request000: Finished\n",
      "20.4012 Request001: Incoming request\n",
      "20.4012 Request001: Waited  0.000\n",
      "25.4529 Request002: Incoming request\n",
      "31.6929 Request001: Finished\n",
      "31.6929 Request002: Waited  6.240\n",
      "37.1734 Request002: Finished\n",
      "69.9987 Request003: Incoming request\n",
      "69.9987 Request003: Waited  0.000\n",
      "70.6037 Request004: Incoming request\n",
      "71.1416 Request005: Incoming request\n",
      "77.0378 Request003: Finished\n",
      "77.0378 Request004: Waited  6.434\n",
      "79.5281 Request004: Finished\n",
      "79.5281 Request005: Waited  8.387\n",
      "88.4262 Request005: Finished\n",
      "92.1314 Request006: Incoming request\n",
      "92.1314 Request006: Waited  0.000\n",
      "108.5211 Request006: Finished\n",
      "125.2862 Request007: Incoming request\n",
      "125.2862 Request007: Waited  0.000\n",
      "126.9760 Request007: Finished\n",
      "149.2420 Request008: Incoming request\n",
      "149.2420 Request008: Waited  0.000\n",
      "150.2153 Request008: Finished\n",
      "212.2724 Request009: Incoming request\n",
      "212.2724 Request009: Waited  0.000\n",
      "214.3068 Request010: Incoming request\n",
      "221.5289 Request009: Finished\n",
      "221.5289 Request010: Waited  7.222\n",
      "229.2126 Request010: Finished\n",
      "247.2214 Request011: Incoming request\n",
      "247.2214 Request011: Waited  0.000\n",
      "255.2519 Request011: Finished\n",
      "319.5457 Request012: Incoming request\n",
      "319.5457 Request012: Waited  0.000\n",
      "339.3295 Request012: Finished\n",
      "354.9149 Request013: Incoming request\n",
      "354.9149 Request013: Waited  0.000\n",
      "355.3840 Request013: Finished\n",
      "372.1393 Request014: Incoming request\n",
      "372.1393 Request014: Waited  0.000\n",
      "372.9708 Request014: Finished\n",
      "377.3120 Request015: Incoming request\n",
      "377.3120 Request015: Waited  0.000\n",
      "380.5690 Request015: Finished\n",
      "382.6119 Request016: Incoming request\n",
      "382.6119 Request016: Waited  0.000\n",
      "387.2352 Request016: Finished\n",
      "402.8066 Request017: Incoming request\n",
      "402.8066 Request017: Waited  0.000\n",
      "407.5086 Request018: Incoming request\n",
      "428.3931 Request019: Incoming request\n",
      "430.3982 Request017: Finished\n",
      "430.3982 Request018: Waited 22.890\n",
      "432.1472 Request020: Incoming request\n",
      "432.1823 Request018: Finished\n",
      "432.1823 Request019: Waited  3.789\n",
      "441.6903 Request021: Incoming request\n",
      "442.3988 Request019: Finished\n",
      "442.3988 Request020: Waited 10.252\n",
      "457.9718 Request022: Incoming request\n",
      "460.9045 Request020: Finished\n",
      "460.9045 Request021: Waited 19.214\n",
      "461.2307 Request021: Finished\n",
      "461.2307 Request022: Waited  3.259\n",
      "465.0207 Request022: Finished\n",
      "487.8939 Request023: Incoming request\n",
      "487.8939 Request023: Waited  0.000\n",
      "494.1263 Request024: Incoming request\n",
      "516.5251 Request023: Finished\n",
      "516.5251 Request024: Waited 22.399\n",
      "527.1800 Request024: Finished\n",
      "535.9352 Request025: Incoming request\n",
      "535.9352 Request025: Waited  0.000\n",
      "542.0758 Request025: Finished\n",
      "546.0066 Request026: Incoming request\n",
      "546.0066 Request026: Waited  0.000\n",
      "552.1611 Request027: Incoming request\n",
      "554.2476 Request026: Finished\n",
      "554.2476 Request027: Waited  2.087\n",
      "558.2574 Request028: Incoming request\n",
      "568.4540 Request029: Incoming request\n",
      "577.0581 Request027: Finished\n",
      "577.0581 Request028: Waited 18.801\n",
      "578.0112 Request028: Finished\n",
      "578.0112 Request029: Waited  9.557\n",
      "578.4938 Request029: Finished\n",
      "688.5864 Request030: Incoming request\n",
      "688.5864 Request030: Waited  0.000\n",
      "690.9092 Request031: Incoming request\n",
      "701.8783 Request032: Incoming request\n",
      "704.2924 Request030: Finished\n",
      "704.2924 Request031: Waited 13.383\n",
      "711.4914 Request033: Incoming request\n",
      "711.8238 Request031: Finished\n",
      "711.8238 Request032: Waited  9.945\n",
      "711.9392 Request032: Finished\n",
      "711.9392 Request033: Waited  0.448\n",
      "724.6947 Request033: Finished\n",
      "782.3547 Request034: Incoming request\n",
      "782.3547 Request034: Waited  0.000\n",
      "785.4584 Request034: Finished\n",
      "805.2505 Request035: Incoming request\n",
      "805.2505 Request035: Waited  0.000\n",
      "810.9557 Request035: Finished\n",
      "825.7371 Request036: Incoming request\n",
      "825.7371 Request036: Waited  0.000\n",
      "837.8297 Request037: Incoming request\n",
      "843.9436 Request038: Incoming request\n",
      "846.6000 Request036: Finished\n",
      "846.6000 Request037: Waited  8.770\n",
      "847.8798 Request039: Incoming request\n",
      "854.9689 Request040: Incoming request\n",
      "867.0421 Request037: Finished\n",
      "867.0421 Request038: Waited 23.099\n",
      "873.7483 Request041: Incoming request\n",
      "881.4185 Request038: Finished\n",
      "881.4185 Request039: Waited 33.539\n",
      "888.9762 Request039: Finished\n",
      "888.9762 Request040: Waited 34.007\n",
      "888.9819 Request040: Finished\n",
      "888.9819 Request041: Waited 15.234\n",
      "889.2519 Request042: Incoming request\n",
      "889.6453 Request043: Incoming request\n",
      "892.8999 Request041: Finished\n",
      "892.8999 Request042: Waited  3.648\n",
      "896.5745 Request042: Finished\n",
      "896.5745 Request043: Waited  6.929\n",
      "897.1713 Request043: Finished\n",
      "931.8387 Request044: Incoming request\n",
      "931.8387 Request044: Waited  0.000\n",
      "932.7341 Request044: Finished\n",
      "973.9149 Request045: Incoming request\n",
      "973.9149 Request045: Waited  0.000\n",
      "987.2252 Request046: Incoming request\n",
      "988.2112 Request045: Finished\n",
      "988.2112 Request046: Waited  0.986\n",
      "994.6601 Request046: Finished\n",
      "1016.2597 Request047: Incoming request\n",
      "1016.2597 Request047: Waited  0.000\n",
      "1032.2211 Request048: Incoming request\n",
      "1036.8509 Request047: Finished\n",
      "1036.8509 Request048: Waited  4.630\n",
      "1043.2242 Request049: Incoming request\n",
      "1044.6009 Request048: Finished\n",
      "1044.6009 Request049: Waited  1.377\n",
      "1048.3364 Request049: Finished\n",
      "1069.4057 Request050: Incoming request\n",
      "1069.4057 Request050: Waited  0.000\n",
      "1075.1701 Request050: Finished\n",
      "1175.9786 Request051: Incoming request\n",
      "1175.9786 Request051: Waited  0.000\n",
      "1178.5236 Request051: Finished\n",
      "1190.5573 Request052: Incoming request\n",
      "1190.5573 Request052: Waited  0.000\n",
      "1193.1724 Request052: Finished\n",
      "1198.8096 Request053: Incoming request\n",
      "1198.8096 Request053: Waited  0.000\n",
      "1203.7844 Request054: Incoming request\n",
      "1208.7820 Request053: Finished\n",
      "1208.7820 Request054: Waited  4.998\n",
      "1208.9843 Request055: Incoming request\n",
      "1210.4541 Request056: Incoming request\n",
      "1228.4171 Request054: Finished\n",
      "1228.4171 Request055: Waited 19.433\n",
      "1229.8364 Request055: Finished\n",
      "1229.8364 Request056: Waited 19.382\n",
      "1232.5655 Request057: Incoming request\n",
      "1249.4935 Request058: Incoming request\n",
      "1257.2495 Request056: Finished\n",
      "1257.2495 Request057: Waited 24.684\n",
      "1259.3617 Request057: Finished\n",
      "1259.3617 Request058: Waited  9.868\n",
      "1260.3813 Request058: Finished\n",
      "1280.2005 Request059: Incoming request\n",
      "1280.2005 Request059: Waited  0.000\n",
      "1286.4933 Request059: Finished\n",
      "1291.4798 Request060: Incoming request\n",
      "1291.4798 Request060: Waited  0.000\n",
      "1317.5981 Request061: Incoming request\n",
      "1319.6702 Request062: Incoming request\n",
      "1327.9594 Request063: Incoming request\n",
      "1332.9352 Request060: Finished\n",
      "1332.9352 Request061: Waited 15.337\n",
      "1333.6772 Request064: Incoming request\n",
      "1338.8884 Request061: Finished\n",
      "1338.8884 Request062: Waited 19.218\n",
      "1341.7627 Request062: Finished\n",
      "1341.7627 Request063: Waited 13.803\n",
      "1344.6367 Request065: Incoming request\n",
      "1356.3452 Request066: Incoming request\n",
      "1367.4367 Request063: Finished\n",
      "1367.4367 Request064: Waited 33.760\n",
      "1372.3299 Request067: Incoming request\n",
      "1408.4910 Request068: Incoming request\n",
      "1439.8336 Request064: Finished\n",
      "1439.8336 Request065: Waited 95.197\n",
      "1441.6526 Request065: Finished\n",
      "1441.6526 Request066: Waited 85.307\n",
      "1448.3009 Request066: Finished\n",
      "1448.3009 Request067: Waited 75.971\n",
      "1450.7057 Request067: Finished\n",
      "1450.7057 Request068: Waited 42.215\n",
      "1455.8313 Request068: Finished\n",
      "1460.6642 Request069: Incoming request\n",
      "1460.6642 Request069: Waited  0.000\n",
      "1461.8727 Request070: Incoming request\n",
      "1468.0359 Request071: Incoming request\n",
      "1480.1756 Request072: Incoming request\n",
      "1502.8693 Request069: Finished\n",
      "1502.8693 Request070: Waited 40.997\n",
      "1510.9834 Request070: Finished\n",
      "1510.9834 Request071: Waited 42.947\n",
      "1523.6564 Request071: Finished\n",
      "1523.6564 Request072: Waited 43.481\n",
      "1525.3382 Request072: Finished\n",
      "1543.2550 Request073: Incoming request\n",
      "1543.2550 Request073: Waited  0.000\n",
      "1550.2947 Request074: Incoming request\n",
      "1551.9105 Request073: Finished\n",
      "1551.9105 Request074: Waited  1.616\n",
      "1552.4992 Request074: Finished\n",
      "1565.9209 Request075: Incoming request\n",
      "1565.9209 Request075: Waited  0.000\n",
      "1583.4709 Request076: Incoming request\n",
      "1585.0751 Request075: Finished\n",
      "1585.0751 Request076: Waited  1.604\n",
      "1585.9102 Request076: Finished\n",
      "1586.8969 Request077: Incoming request\n",
      "1586.8969 Request077: Waited  0.000\n",
      "1591.0085 Request078: Incoming request\n",
      "1596.3714 Request079: Incoming request\n",
      "1598.1428 Request077: Finished\n",
      "1598.1428 Request078: Waited  7.134\n",
      "1607.1696 Request078: Finished\n",
      "1607.1696 Request079: Waited 10.798\n",
      "1616.8292 Request079: Finished\n",
      "1640.5692 Request080: Incoming request\n",
      "1640.5692 Request080: Waited  0.000\n",
      "1647.9671 Request080: Finished\n",
      "1651.4371 Request081: Incoming request\n",
      "1651.4371 Request081: Waited  0.000\n",
      "1664.0316 Request081: Finished\n",
      "1706.0143 Request082: Incoming request\n",
      "1706.0143 Request082: Waited  0.000\n",
      "1711.4684 Request083: Incoming request\n",
      "1717.1522 Request082: Finished\n",
      "1717.1522 Request083: Waited  5.684\n",
      "1718.6019 Request084: Incoming request\n",
      "1720.1080 Request085: Incoming request\n",
      "1731.0900 Request083: Finished\n",
      "1731.0900 Request084: Waited 12.488\n",
      "1731.8509 Request084: Finished\n",
      "1731.8509 Request085: Waited 11.743\n",
      "1734.2481 Request085: Finished\n",
      "1849.5554 Request086: Incoming request\n",
      "1849.5554 Request086: Waited  0.000\n",
      "1855.7186 Request087: Incoming request\n",
      "1870.8303 Request086: Finished\n",
      "1870.8303 Request087: Waited 15.112\n",
      "1872.5471 Request087: Finished\n",
      "1898.0026 Request088: Incoming request\n",
      "1898.0026 Request088: Waited  0.000\n",
      "1907.4618 Request088: Finished\n",
      "1933.8872 Request089: Incoming request\n",
      "1933.8872 Request089: Waited  0.000\n",
      "1933.9658 Request089: Finished\n",
      "2021.1052 Request090: Incoming request\n",
      "2021.1052 Request090: Waited  0.000\n",
      "2031.9934 Request090: Finished\n",
      "2055.0819 Request091: Incoming request\n",
      "2055.0819 Request091: Waited  0.000\n",
      "2056.3085 Request091: Finished\n",
      "2110.9966 Request092: Incoming request\n",
      "2110.9966 Request092: Waited  0.000\n",
      "2113.2608 Request093: Incoming request\n",
      "2114.1759 Request092: Finished\n",
      "2114.1759 Request093: Waited  0.915\n",
      "2116.4525 Request093: Finished\n",
      "2131.8296 Request094: Incoming request\n",
      "2131.8296 Request094: Waited  0.000\n",
      "2138.5343 Request094: Finished\n",
      "2151.9450 Request095: Incoming request\n",
      "2151.9450 Request095: Waited  0.000\n",
      "2152.9134 Request095: Finished\n",
      "2199.0936 Request096: Incoming request\n",
      "2199.0936 Request096: Waited  0.000\n",
      "2199.1291 Request096: Finished\n",
      "2210.1118 Request097: Incoming request\n",
      "2210.1118 Request097: Waited  0.000\n",
      "2213.1493 Request097: Finished\n",
      "2239.6029 Request098: Incoming request\n",
      "2239.6029 Request098: Waited  0.000\n",
      "2245.1836 Request098: Finished\n",
      "2266.6393 Request099: Incoming request\n",
      "2266.6393 Request099: Waited  0.000\n",
      "2288.1042 Request099: Finished\n"
     ]
    }
   ],
   "source": [
    "server = simpy.Resource(env, capacity=1)\n",
    "env.process(workload(env, REQ_TOTAL, ARRIVAL_RATE, server))\n",
    "env.run()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "记录延迟数据"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 98,
   "metadata": {},
   "outputs": [],
   "source": [
    "with open(\"latency.csv\", \"w+\") as tracefile:\n",
    "    tracefile.write(\"# latency\\n\")\n",
    "    tracefile.writelines([str(l) + '\\n' for l in latency])"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3.9.7 ('lab')",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.7"
  },
  "orig_nbformat": 4,
  "vscode": {
   "interpreter": {
    "hash": "8af900479a3540cfc38875a4a015127521479f698f39a91084609bef8ead6227"
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
